package com.bsj.media.init;

import com.bsj.media.init.dto.NetDto;
import com.bsj.media.init.dto.NettyHttpDto;
import com.bsj.media.tool.ComboDataTool;
import com.bsj.media.tool.dto.SendData;
import com.bsj.power.common.def.protocol.rtp.RTPInfo;
import com.bsj.power.common.util.DateUtils;
import com.bsj.tools.Conv;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import static com.bsj.power.common.util.DateUtils.TIME_STANDARD_FORMAT2;

/**
 * key为sim+管道,管理多路链路播放关闭
 */
@Slf4j
public class SendCachedData {

    private String id;

    public SendCachedData(String idNow) {
        id = idNow;
    }

    //RTP数据组合器
    private ComboDataTool comboDataTool = new ComboDataTool();

    //需要发送裸流的数据
    private Map<ChannelHandlerContext, NetDto> natureMap = new HashMap<>();

    //需要根据http返回的数据集
    private Map<ChannelHandlerContext, NetDto> flvMap = new HashMap<>();

//    public void pushDataHttp(ChannelHandlerContext channelHandlerContext) {
//        NetDto netDto = flvMap.get(channelHandlerContext);
//        if (netDto == null) {
//            NettyHttpDto nettyHttpDto = new NettyHttpDto(channelHandlerContext);
//            nettyHttpDto.init(id);
//            flvMap.put(channelHandlerContext, nettyHttpDto);
//        } else {
//            log.warn("重复的http请求");
//        }
//    }

    public void pushDataHttpLiveVideo(String mediaType, ChannelHandlerContext channelHandlerContext) {
        NetDto netDto = flvMap.get(channelHandlerContext);
        if (netDto == null) {
            NettyHttpDto nettyHttpDto = new NettyHttpDto(channelHandlerContext, mediaType);
            nettyHttpDto.init(id);
            nettyHttpDto.initLiveVideo();
            flvMap.put(channelHandlerContext, nettyHttpDto);
        } else {
            log.warn("重复的http请求");
        }
    }

    public void pushDataDownVideo(String mediaType, ChannelHandlerContext channelHandlerContext, String fileName) {
        NetDto netDto = flvMap.get(channelHandlerContext);
        if (netDto == null) {
            NettyHttpDto nettyHttpDto = new NettyHttpDto(channelHandlerContext, mediaType);
            nettyHttpDto.init(id);
            String[] split = fileName.split("\\.");
            String[] timeSplit = split[0].split("_");
            Date startTime = DateUtils.strToDate(TIME_STANDARD_FORMAT2, timeSplit[0]);
            Date endTime = DateUtils.strToDate(TIME_STANDARD_FORMAT2, timeSplit[1]);
            //加2分钟
//            long start = startTime.getTime() + 120000;
//            long end = endTime.getTime() + 120000;
            long start = startTime.getTime();
            long end = endTime.getTime();
            //保存两个时间间隔有多少毫秒，然后用设备接收的数据时间比较，确定关闭的方法
            nettyHttpDto.setEndTime(end - start);
            nettyHttpDto.initLiveVideo();
            nettyHttpDto.downFile(fileName);
            flvMap.put(channelHandlerContext, nettyHttpDto);
        } else {
            log.warn("重复的http请求");
        }
    }

    public void close() {
        if (natureMap != null && !natureMap.isEmpty()) {
            for (Map.Entry<ChannelHandlerContext, NetDto> entry : natureMap.entrySet()) {
                ChannelHandlerContext key = entry.getKey();
                NetDto value = entry.getValue();
                value.stop();
                key.close();
            }
        }
        if (flvMap != null && !flvMap.isEmpty()) {
            for (Map.Entry<ChannelHandlerContext, NetDto> entry : flvMap.entrySet()) {
                ChannelHandlerContext key = entry.getKey();
                NetDto value = entry.getValue();
                value.stop();
                key.close();
            }
        }
    }

    private byte[] changeFDData(byte[] h264) {
        if (h264 == null) {
            return null;
        }
        int length = h264.length;
        //2字节头，6字节设备号，1消息类型，4字节长度，消息体，1字节校验位，1字节结束表示
        int len = 2 + 6 + 1 + 4 + length + 1 + 1;
        int offset = 0;
        byte[] result = new byte[len];
        result[offset] = (byte) 0xFD;
        offset = offset + 1;
        result[offset] = (byte) 0xFD;
        offset = offset + 1;
        offset = offset + 6;
        result[offset] = 0x02;
        offset = offset + 1;
        Conv.setIntNetOrder(result, offset, length);
        offset = offset + 4;
        System.arraycopy(h264, 0, result, offset, length);
        offset = offset + length;
        offset = offset + 1;
        result[offset] = 0x0D;
        offset = offset + 1;
        return result;
    }

//    public void pushDataNature(ChannelHandlerContext channelHandlerContext) {
//        NettyTcpDto nettyTcpDto = new NettyTcpDto(channelHandlerContext);
//        nettyTcpDto.init(id);
//        natureMap.put(channelHandlerContext, nettyTcpDto);
//    }

//    public void handleData(RTPInfo rtpInfo) {
//        if (flvMap != null && !flvMap.isEmpty()) {
//            SendData sendData = comboDataTool.pushCombination(rtpInfo);
//            if (sendData != null) {
//                //是I帧，1是P帧，2是B帧，3是音频帧，4是透传数据
//                int dataType = sendData.getDataType();
//                //FD数据
//                byte[] needData = sendData.getNeedData();
//                for (Map.Entry<ChannelHandlerContext, NetDto> nettyDtoMap : flvMap.entrySet()) {
//                    NetDto value = nettyDtoMap.getValue();
//                    value.push(needData);
//                }
//            }
//            if (natureMap != null && !natureMap.isEmpty()) {
//                //h264或h265数据
//                byte[] data = sendData.getData();
//                for (Map.Entry<ChannelHandlerContext, NetDto> nettyDtoMap : natureMap.entrySet()) {
//                    NetDto value = nettyDtoMap.getValue();
//                    value.push(changeFDData(data));
//                }
//            }
//        }
//    }

        public void handleData(RTPInfo rtpInfo) {
        if (flvMap != null && !flvMap.isEmpty()) {
            SendData sendData = comboDataTool.pushAssemble(rtpInfo);
            if (sendData != null) {
                //是I帧，1是P帧，2是B帧，3是音频帧，4是透传数据
//                int dataType = sendData.getDataType();
                //FD数据
                byte[] needData = sendData.getNeedData();
                for (Map.Entry<ChannelHandlerContext, NetDto> nettyDtoMap : flvMap.entrySet()) {
                    NetDto value = nettyDtoMap.getValue();
                    value.push(needData, sendData.getTime());
                }
            }
            if (natureMap != null && !natureMap.isEmpty()) {
                //h264或h265数据
                byte[] data = sendData.getData();
                for (Map.Entry<ChannelHandlerContext, NetDto> nettyDtoMap : natureMap.entrySet()) {
                    NetDto value = nettyDtoMap.getValue();
                    value.push(changeFDData(data), sendData.getTime());
                }
            }
        }
    }

    public void del(ChannelHandlerContext channelHandlerContext) {
        NetDto remove = flvMap.remove(channelHandlerContext);
        if (remove != null) {
            remove.stop();
            natureMap.remove(channelHandlerContext);
        }
    }

    public boolean clearFlag() {
        if (natureMap.isEmpty() && flvMap.isEmpty()) {
            return true;
        } else {
            return false;
        }
    }

    public int saveDto() {
        return flvMap == null ? 0 : flvMap.size();
    }
}
